#include "OutputSourceManager.h"
#include "HdmiOutputSource.h"
#include "SqlTableHelper.h"
namespace Media{

OutputSourceManager::Ptr OutputSourceManager::Instance(){
    static auto ptr = std::make_shared<OutputSourceManager>();
    return ptr;
}
OutputSourceManager::OutputSourceManager(){
    m_sql = SqlTableOp::Instance();
    init();
}
OutputSourceManager::~OutputSourceManager()= default;


bool OutputSourceManager::AddSource(const outputSourceTable& config, uint32_t& id){
    if(m_sql->InsertTable<outputSourceTable>(config, id)){
        //create outputSource
        SourceInterfaceEnum inType = SourceInterConnectMap[config.m_con_type];
        SourceMediaType mediaType = VIDEO;
        if(config.m_type == MediaVideo){
            mediaType = VIDEO;
        }else if(config.m_type == MediaAudio){
            mediaType = AUDIO;
        }else if(config.m_type == MediaAll){
            mediaType = VA;
        }else{
            return false;
        }

        SourceConfig sConfig;
        sConfig.m_sourceType = OUTPUT;
        sConfig.m_isCustomCreated = config.m_custom;
        sConfig.m_sourceInterface = inType;
        sConfig.m_sourceMediaType = mediaType;
        sConfig.m_sourceContent = config.m_content;

        auto sourcePtr = createOutputSource(sConfig);
        if(sourcePtr){
            std::lock_guard<std::recursive_mutex> guard(m_mux);
            m_sources[id] = sourcePtr;
            sourcePtr->Start();
            return true;
        }
    }
    return false;
}
bool OutputSourceManager::RemoveSource(uint32_t id){
    if(m_sql->DelTable<inputSourceTable>(id)){
        std::lock_guard<std::recursive_mutex> guard(m_mux);
        if(m_sources.find(id) != m_sources.end()){
            m_sources.erase(id);
            return true;
        }
    }
    return false;
}
bool OutputSourceManager::GetOneSourceConfig(uint32_t id, outputSourceTable& config){
    return m_sql->GetOneTable<outputSourceTable>(id, config);
}

bool OutputSourceManager::GetAllSourceConfig(std::vector<outputSourceTable>& configs){
    return m_sql->GetAllTable<outputSourceTable>(configs);
}



void OutputSourceManager::init(){
    std::vector<outputSourceTable> tbs;
    if(m_sql->Instance()->GetAllTable<outputSourceTable>(tbs)){
        for(const auto& tb:tbs){
            if(SourceInterConnectMap.find(tb.m_con_type) != SourceInterConnectMap.end()){
                SourceInterfaceEnum inType = SourceInterConnectMap[tb.m_con_type];
                SourceMediaType mediaType = VIDEO;
                if(tb.m_type == MediaVideo){
                    mediaType = VIDEO;
                }else if(tb.m_type == MediaAudio){
                    mediaType = AUDIO;
                }else if(tb.m_type == MediaAll){
                    mediaType = VA;
                }else{
                    continue;
                }

                SourceConfig config;
                config.m_sourceType = INPUT;
                config.m_isCustomCreated = tb.m_custom;
                config.m_sourceInterface = inType;
                config.m_sourceMediaType = mediaType;
                config.m_sourceContent = tb.m_content;
                auto source = createOutputSource(config);
                if(source){
                    std::lock_guard<std::recursive_mutex> guard(m_mux);
                    m_sources[tb.m_id] = source;
                }
            }
        }
    }
}

OutputSource::Ptr OutputSourceManager::GetSource(uint32_t id){
    std::lock_guard<std::recursive_mutex> guard(m_mux);
    OutputSource::Ptr source;
    if(m_sources.find(id) != m_sources.end()){
        source = m_sources[id];
    }
    return source;
}

void OutputSourceManager::outInterfaceCheck(){

}

OutputSource::Ptr OutputSourceManager::createOutputSource(const SourceConfig& config){
    OutputSource::Ptr source;
    if(config.m_sourceInterface == HDMI){
        source = HdmiOutputSource::Instance();
    }
    return source;
}

}